﻿using System.Threading.Tasks;
using AutoMapper;
using Nest;
namespace Journeo_backend.Services.Implementations
{
    public class PlanAttractionService : IPlanAttractionService
    {
        private readonly IMapper _mapper;
        private readonly ApplicationDbContext _context;
        public PlanAttractionService(IMapper mapper, ApplicationDbContext context)
        {
            _mapper = mapper;
            _context = context;
        }

        // 创建一个新的计划景点
        public async Task<Response<PlanAttraction>> CreatPlanAttraction(PlanAttractionDTO planAttractionDTO)
        {
            try
            {
                PlanAttraction planAttraction = _mapper.Map<PlanAttraction>(planAttractionDTO);
                _context.PlanAttraction.Add(planAttraction);

                await _context.SaveChangesAsync();
                return new Response<PlanAttraction>(planAttraction);
            }
            catch (Exception e)
            {
                return new Response<PlanAttraction>("error", e.Message);
            }
        }


        // 更新一个计划景点
        public async Task<Response<PlanAttraction>> UpdatePlanAttraction(long planAttractionId, PlanAttractionDTO planAttractionDTO)
        {
            try
            {
                PlanAttraction planAttraction = await _context.PlanAttraction.FirstOrDefaultAsync(p => p.PlanAttractionId == planAttractionId);

                if (planAttraction != null)
                {
                    planAttraction = _mapper.Map(planAttractionDTO, planAttraction);
                    planAttraction.UpdatedAt = DateTime.Now;
                }
                else
                {
                    return new Response<PlanAttraction>("error", Messages.FAILED);
                }

                await _context.SaveChangesAsync();
                return new Response<PlanAttraction>(planAttraction);
            }
            catch (Exception e)
            {
                return new Response<PlanAttraction>("error", e.Message);
            }
        }


        // 删除一个计划景点
        public async Task<Response<string>> DeletePlanAttraction(long planAttractionId)
        {
            try
            {
                PlanAttraction planAttraction = await _context.PlanAttraction.FirstOrDefaultAsync(p => p.PlanAttractionId == planAttractionId);
                if (planAttraction != null)
                {
                    _context.PlanAttraction.Remove(planAttraction);
                }
                await _context.SaveChangesAsync();
                return new Response<string>(Messages.SUCCESS);
            }
            catch (Exception e)
            {
                return new Response<string>("error", e.Message);
            }
        }


        // 通过ID获取计划景点
        public async Task<Response<PlanAttraction>> GetPlanAttractionById(long planAttractionId)
        {
            try
            {
                PlanAttraction planAttraction = await _context.PlanAttraction.FindAsync(planAttractionId);
                return new Response<PlanAttraction>(planAttraction);
            }
            catch (Exception e)
            {
                return new Response<PlanAttraction>("error", e.Message);
            }
        }


        // 通过计划ID获取计划景点
        public async Task<PageResponse<PlanAttraction>> GetPlanAttractionsByPlanId(long planId, int pageNumber, int pageSize)
        {
            try
            {
                var searchResponse = _context.PlanAttraction.Where(p => p.PlanId == planId).ToList();
                var planAttractions = searchResponse.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();
                return new PageResponse<PlanAttraction>(planAttractions, pageNumber, pageSize, searchResponse.Count);
            }
            catch (Exception e)
            {
                return await Task.FromResult(new PageResponse<PlanAttraction>("error", e.Message, null, pageNumber, pageSize, 0));
            }
        }


        // 通过计划ID删除计划景点
        public async Task<Response<string>> DeletePlanAttractionsByPlanId(long planId)
        {
            try
            {
                var planAttractions = _context.PlanAttraction.Where(p => p.PlanId == planId).ToList();
                if (planAttractions.Any())
                {
                    _context.RemoveRange(planAttractions);
                    await _context.SaveChangesAsync();
                }
                return new Response<string>(Messages.SUCCESS);

            }
            catch (Exception e)
            {
                return new Response<string>("error", e.Message);
            }
        }


        // 改变访问顺序（默认pageNumber=1，pageSize=maxInt）
        // 需要同步编辑TransportationPlan的VisitOrder，删除调换位置的PlanAttraction的TransportationPlan
        public async Task<Response<string>> ChangeVisitOrder(long planAttractionId, int newVisitOrder)
        {
            var planAttraction = _context.PlanAttraction.FirstOrDefault(p => p.PlanAttractionId == planAttractionId);
            try
            {
                if (planAttraction != null)
                {
                    //原始序号
                    int originOrder = planAttraction.VisitOrder;
                    var planAttrationsChange = _context.PlanAttraction.Where(p => p.PlanId == planAttraction.PlanId).OrderBy(p => p.VisitOrder).ToList();
                    //根据先后顺序来改变序号
                    if (originOrder > newVisitOrder)
                    {
                        foreach (var item in planAttrationsChange.Where(p => p.VisitOrder < originOrder && p.VisitOrder >= newVisitOrder))
                        {
                            item.VisitOrder += 1;
                        }
                    }
                    else
                    {
                        foreach (var item in planAttrationsChange.Where(p => p.VisitOrder > originOrder && p.VisitOrder <= newVisitOrder))
                        {
                            item.VisitOrder -= 1;
                        }
                    }

                    //将结果存入数据库
                    planAttraction.VisitOrder = newVisitOrder;
                    _context.PlanAttraction.UpdateRange(planAttrationsChange);
                    _context.PlanAttraction.Update(planAttraction);
                    await _context.SaveChangesAsync();
                    return new Response<string>(Messages.SUCCESS);
                }
                else
                {
                    return new Response<string>(Messages.FAILED);
                }
            }
            catch (Exception e)
            {
                return new Response<string>("error", e.Message);
            }
        }
    }
}
